package com.xbdun.comweb.bmp.interceptor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.xbdun.common.api.XbdUnStringResult;
import com.xbdun.common.constant.XbdunLoginConst;
import com.xbdun.common.enums.UserRolesEnums;
import com.xbdun.common.exceptions.BizException;
import com.xbdun.comweb.bmp.constants.HtmlConstant;
import com.xbdun.comweb.bmp.constants.SessionConstant;
import com.xbdun.comweb.bmp.enums.SysEnums;
import com.xbdun.comweb.bmp.frame.annotation.XbdunLogin;
import com.xbdun.comweb.bmp.session.CurrentUserInfo;
import com.xbdun.comweb.bmp.util.UserInfoUtil;

/**
 * 用户登录拦截器
 * @author zhanggt
 */
@Component
public class UserInterceptor extends HandlerInterceptorAdapter {
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception {
		if(!handler.getClass().isAssignableFrom(HandlerMethod.class)){return true;}
		HandlerMethod handlerMethod = (HandlerMethod) handler;
		if (isDefAnnoteation(handlerMethod, XbdunLogin.class)) {
			CurrentUserInfo userInfo = UserInfoUtil.getCurrentUserInfoExcption(request);
			request.setAttribute(SessionConstant.REQUEST_USER_SESSION,userInfo);
			// MEMBER(1,"会员"),ADMIN(2,"管理员"),SUPPERADMIN(3,"超级管理员"),ADMINS(4,"管理员/超级管理员"),XBDADMINT(5,"平台管理员");
			if (handlerMethod.getMethod().isAnnotationPresent(XbdunLogin.class)) {
				//注册在方法上权限
				checkUserRole(request,handlerMethod.getMethod().getAnnotation(XbdunLogin.class).value(),handlerMethod,userInfo);
			}else if(handlerMethod.getMethod().getDeclaringClass().isAnnotationPresent(XbdunLogin.class)) {
				//注册在类上权限
				checkUserRole(request,handlerMethod.getMethod().getDeclaringClass().getAnnotation(XbdunLogin.class).value(),handlerMethod,userInfo);
			}
		}
		return true;
	}
	
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
		if (null != ex && handler.getClass().isAssignableFrom(HandlerMethod.class)) {
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			if (isDefAnnoteation(handlerMethod, ResponseBody.class)	|| isDefAnnoteation(handlerMethod, RestController.class)) {
				XbdUnStringResult errorMsg = new XbdUnStringResult();
				errorMsg.setBizException(ex);
				request.setAttribute(SysEnums.FROM_RESPONSE_BODY + "", errorMsg);
			}
		}
		//释放原始资源
		request.removeAttribute(SessionConstant.REQUEST_USER_SESSION);
		super.afterCompletion(request, response, handler, ex);
	}

	// 判断是否存在注解
	private boolean isDefAnnoteation(HandlerMethod handlerMethod, Class<? extends Annotation> targClasses) {
		Method method = handlerMethod.getMethod();
		Class<?> clazz = method.getDeclaringClass();
		return (clazz.isAnnotationPresent(targClasses) || method.isAnnotationPresent(targClasses));
	}

	//检测角色是否合法
	private void checkUserRole(HttpServletRequest request,int[] inputInt,HandlerMethod handlerMethod,CurrentUserInfo userInfo)throws Exception{
		boolean isContinue = false;//判断是否角色判断后是否继续
		String[] auths = null;//判断当前访问的页面/按钮权限是否有效
		if (null != inputInt && inputInt.length > 0) {
			if (inputInt.length == 1 && inputInt[0] == -1) {
				throw BizException.POWER_FAIL.newInstance("访问的连接角色并未在系统定义过[-1]");
			}
			//如果是平台管理员就忽略
			if(UserRolesEnums.isXbdAdmin(userInfo.getRoleId()))return;
			//如果上面指定类型不属于自己，那么也要屏蔽掉权限
			for (int i = 0; i < inputInt.length && !isContinue; i++) {
				if (inputInt[i] == XbdunLoginConst.ADMINS) {
					if (userInfo.getRoleId() == XbdunLoginConst.ADMIN || userInfo.getRoleId() == XbdunLoginConst.SUPPERADMIN) {
						isContinue = true;
						break;
					}
				}
				if(inputInt[i]==XbdunLoginConst.MEMBER||inputInt[i]==userInfo.getRoleId()){
					isContinue = true;
					break;
				}
			}
			//如果访问的路径不能为当前角色访问，那么弹出
			if(!isContinue){throw BizException.POWER_FAIL.newInstance("对不起，您当前的角色没有权限访问该路径");}
			//获取到请求连接地址
			if(handlerMethod.getMethod().isAnnotationPresent(RequestMapping.class)){
				auths = handlerMethod.getMethod().getAnnotation(RequestMapping.class).value();
			}else if(handlerMethod.getMethod().isAnnotationPresent(PostMapping.class)){
				auths = handlerMethod.getMethod().getAnnotation(PostMapping.class).value();
			}else{
				auths = handlerMethod.getMethod().getAnnotation(GetMapping.class).value();
			}
			if(null == auths){
				throw BizException.POWER_FAIL.newInstance("系统定义访问路径无效");
			}else{
				String currentOrgAuth = null;	//获取到当前机构所有菜单
				String userAuth = null;			//用户所有权限
				//是否为超级管理员
				if(UserRolesEnums.isSupperAdmin(userInfo.getRoleId())||UserRolesEnums.isAdmins(userInfo.getRoleId())){
					currentOrgAuth = UserInfoUtil.getIUserAuth().getCurrentOrgAuth(userInfo.getOrgCode(), userInfo.getPlatCode());
					if(null==currentOrgAuth){
						throw BizException.POWER_FAIL.newInstance("获取当机构的归属菜单失败，请稍后再试...");
					}
				}else{
					//用户所有权限
					userAuth = UserInfoUtil.getIUserAuth().getUserAuth(UserInfoUtil.getClient(request,userInfo));
					if(null==userAuth){
						throw BizException.POWER_FAIL.newInstance("获取当前用户权限信息失败，请稍后再试...");
					}
				}
				//过滤权限
				for(String strs:auths){
					//主页和系统组件不用过滤
					if(!strs.equals(HtmlConstant.HOME_PAGE)&&!strs.startsWith(HtmlConstant.SYS_ASSEMBLY)){
						isContinue = false;
						if(!strs.startsWith(userInfo.getPlatCode()+"")){
							throw BizException.POWER_FAIL.newInstance("您访问的平台路径并非当前平台的系统");
						}
						//如果是平台管理员，那么就会忽略所有访问地址
						if(null!=currentOrgAuth){
							if(strs.endsWith("X")){
								strs=strs.replaceAll("X", "");
							}
							if(currentOrgAuth.indexOf(","+strs+",")!=-1){
								isContinue = !isContinue;
		            			break;
							}
							//继续判断权限
							continue;
						}
						//不是平台管理，判断当前用户是否存在权限
	            		if(userAuth.indexOf(","+strs+",")!=-1){
	            			isContinue = !isContinue;
	            			break;
	            		}
					}
				}
				//释放资源
				if(null!=currentOrgAuth)currentOrgAuth = null;
				if(null!=userAuth)userAuth = null;
			}
		}
		//权限不够
		if(!isContinue){throw BizException.POWER_FAIL.newInstance("权限不足");}
	}
}
